package com.example.demo.service.impl;


import com.example.demo.dao.UserDao;
import com.example.demo.dto.UserDto;
import com.example.demo.enty.*;
import com.example.demo.enty.Order;
import com.example.demo.service.UserService;
import com.querydsl.core.BooleanBuilder;
import com.querydsl.core.types.Projections;
import com.querydsl.jpa.impl.JPAQueryFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.persistence.EntityManager;
import javax.persistence.criteria.*;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

@Service
@Transactional
public class UserServiceImpl implements UserService {
    @Autowired
    private UserDao userDao;

    @Autowired
    private EntityManager entityManager;
    @Autowired
    private JPAQueryFactory jpaQueryFactory;
    public void test(){
        //添加
        for (Long i=0L;i<10;i++){
            User user = new User(i, "admin", 11);
            entityManager.persist(user);
        }

        //修改
        QUser q = QUser.user;
        BooleanBuilder booleanBuilder=null;
        booleanBuilder = new BooleanBuilder();
        booleanBuilder.and(q.name.like("%赵%")).and(q.age.between(11,19));
        //返回修改的数量
        long len = jpaQueryFactory.update(q).set(q.age, 11).where(booleanBuilder).execute();
        System.out.println(len);

        //删除
        long delete = jpaQueryFactory.delete(q).where(booleanBuilder).execute();
        System.out.println("输出删除的语句"+delete);

        //条件查询
        booleanBuilder.and(q.age.between(11,19));
        List<User> fetch = jpaQueryFactory.selectFrom(q).where(booleanBuilder).fetch();
        System.out.println(fetch);
        //封装条件查询
        List<String> fetch1 = jpaQueryFactory.select(q.name).from(q).where(booleanBuilder).orderBy(q.id.desc()).fetch();
        System.out.println("fetch1 = " + fetch1);
        //根据条件将结果查询出来之后封装到User对象中

        List<User> fetch2 = jpaQueryFactory.select(Projections.bean(User.class, q.id, q.name)).from(q).where(booleanBuilder).orderBy(q.id.desc()).fetch();
        System.out.println("fetch2 = " + fetch2);
        long l = jpaQueryFactory.selectFrom(q).where(booleanBuilder).fetchCount();
        System.out.println("查询符合条件的总条数 " + l);

        List<String> fetch3 = jpaQueryFactory.selectDistinct(q.name).from(q).where(booleanBuilder).orderBy(q.id.desc()).fetch();
        System.out.println("去重查询" + fetch3);
        //分页


        /*
        *
        *
        public List<Tuple> findCityAndHotel(Predicate predicate) {
        JPAQueryFactory queryFactory = new JPAQueryFactory(em);
        JPAQuery<Tuple> jpaQuery = queryFactory.select(QTCity.tCity,QTHotel.tHotel)
                                        .from(QTCity.tCity)
                                        .leftJoin(QTHotel.tHotel)
                                        .on(QTHotel.tHotel.city.longValue().eq(QTCity.tCity.id.longValue()));
        //添加查询条件
        jpaQuery.where(predicate);
        //拿到结果
        return jpaQuery.fetch();
    }

        *
        *
        * */



    }

    @Override
    public List<User> findAll() {
        return userDao.findAll(new Specification<User>() {
            @Override
            public Predicate toPredicate(Root<User> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {

                Path<String> name = root.get("name");
                Predicate like = criteriaBuilder.like(name, "赵丽颖");
                criteriaQuery.where(like);
                return null;
            }
        });


        //return userDao.findAll();

    }

    @Override
    public List<User> findByPage(Integer size, Integer page) {

        PageRequest pageRequest = PageRequest.of(page, size);
        List<User> content = userDao.findAll(pageRequest).getContent();
        return content;


    }
    public Page<User> findAllByLikeName(final String name, int page, int count) {
        Page<User> users = userDao.findAll( PageRequest.of(1, 20));
        Specification<User> specification = new Specification<User>() {
            @Override
            public Predicate toPredicate(Root<User> root,
                                         CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {
                Path<String> _name = root.get("name");
                Predicate _key = criteriaBuilder.like(_name, "%"+_name.toString()+ "%");
                return criteriaBuilder.and(_key);
            }
        };
        //Sort sort = new Sort(Sort.Direction.DESC, "id");
        //Pageable pageable =
        PageRequest pageRequest = PageRequest.of(page - 1, count);
        return userDao.findAll(specification, pageRequest);
    }

    @Override
    public List<User> findByPage2(String name, Integer size, Integer page) {
        System.out.println("findAllByLikeName(name,page,size).getContent() = " + findAllByLikeName(name, page, size).getContent());
        return findAllByLikeName(name,page,size).getContent();

       /* PageRequest pageRequest = PageRequest.of(page, size);
       return userDao.findAll(new Specification<User>() {
            @Override
            public Predicate toPredicate(Root<User> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {

                Path<String> name1 = root.get("name");
                Predicate like = criteriaBuilder.like(name1, "%" + name + "%");
                return criteriaBuilder.and(like);
            }
        },pageRequest).getContent();*/

       /* Specification<User> nameList = new Specification<User>() {
            @Override
            public Predicate toPredicate(Root<User> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {

                Path<String> name = root.get("name");

                Predicate like = criteriaBuilder.like(name, "%" + name + "%");
                return criteriaBuilder.and(like);
            }
        };
        PageRequest pageRequest = PageRequest.of(page, size);
        Page<User> all = userDao.findAll(nameList, pageRequest);
        return all.getContent();*/
    }

    @Override
    public void save() {
        userDao.save(new User(4L,"zys",12));
    }

    @Override
    public User findAlld(User user) {

        Specification<User> sp=(root, cq, cb) ->
            cq.where(cb.equal(root.get("id"),1L)).getRestriction();
        Optional<User> one = userDao.findOne(sp);
        if (one.isPresent()) {
            System.out.println(one);
        }
        return one.get();


    }

    @Override
    public List<User> findBymohu() {

        Specification<User> sp=(root,cq,cb)->
                cq.where(cb.like(root.get("name"),'%'+"赵"+'%')).getRestriction();

        List<User> all = userDao.findAll(sp);
        if (!CollectionUtils.isEmpty(all)) {
            //不为空

            return all.stream().collect(Collectors.toList());

        }
        return null;
    }

    @Override
    public List<User> findByPages() {

        Specification<User> sp=(root,cq,cb)->
        cq.where(cb.equal(root.get("name"),"赵丽颖")).getRestriction();

        Page<User> all = userDao.findAll(sp, PageRequest.of(0, 1));

        System.out.println("总记录数："+all.getTotalElements());
        System.out.println("总页数"+all.getTotalPages());
        System.out.println("当前页显示的数据："+all.getSize());
        return all.stream().collect(Collectors.toList());
    }

    //单表简单查询所有
    @Override
    public List<User> findAllJpaDsl() {
        QUser user = QUser.user;
        return jpaQueryFactory.selectFrom(user).fetch();
    }

    //单表的条件查询
    @Override
    public List<User> findBytioajian(String name) {
        QUser user = QUser.user;
        return jpaQueryFactory.selectFrom(user).where(user.name.eq(name)).fetch();
    }

    //根据id查询数据库
    @Override
    public User findById(Long id) {
        return userDao.findById(id).get();
    }

    //多条件查询
    @Override
    public List<User> findByManyCondition(String name, Integer age) {
        QUser user = QUser.user;
        return jpaQueryFactory.selectFrom(user)
                .where(user.name.eq(name).and(user.age.lt(age))).fetch();
    }

    //使用join进行查询
    @Override
    public List<User> findAllByJoin() {
        QUser user = QUser.user;
        QUser qUser = new QUser("name");
        return jpaQueryFactory
                .selectFrom(user)
                .innerJoin(user)
                .on(qUser.id.intValue()
                        .eq(user.id.intValue())).fetch();

    }

    //根据id进行修改
    @Override
    public void update(String name, Long id) {
        QUser user = QUser.user;
        jpaQueryFactory.update(user).set(user.name,name).where(user.id.longValue().eq(id.longValue())).execute();

    }

    @Override
    public List<User> findByPageDsl(Integer page, Integer size) {

        QUser user = QUser.user;
        int offset;
        if(page==0){
            offset=0;
        }else {
            offset = (page - 1) * size;
        }

        return jpaQueryFactory.selectFrom(user)
                //偏移量，计算公式（page-1）*size
                .offset(offset).limit(size).fetch();
    }

    //查询部分，并且分页
    
    /**
        * @param page
    	* @param size
        * @return java.util.List<com.example.demo.dto.UserDto>
        * @author gmy
        * @date 2020/12/21 15:05
    */
    @Override
    public List<UserDto> findByMapper(Integer page, Integer size) {

        QUser user = QUser.user;
        List<UserDto> userDtoList = jpaQueryFactory.select(
                Projections.bean(
                        UserDto.class,
                        user.name,
                        user.age
                )
        ).from(user).fetch();
        return userDtoList;

       /* QUser user = QUser.user;
        int start;
        if(page==0){
            //表示第一页
            start=0;
        }else {
            start=(page-1)*size;
        }
        jpaQueryFactory
                .select(user.name, user.age)
                .from(user)
                .offset(start)
                .limit(size)
                .fetch()
                .stream()
                .map(tuple->
                                UserDto.builder()
                                        .name(tuple.get(user.name))
                                        .age(tuple.get(user.age))
                                        .id(tuple.get(user.id))
                                        //.birthday(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(tuple.get(user.birthday)))
                                        .build()
                        )
                .collect(Collectors.toList())*/
    }

    @Override
    public List<Order> findByOrder() {
        QUser user = QUser.user;
        QOrder order = QOrder.order;
        return jpaQueryFactory.select(order).from(user).leftJoin(order).where(user.id.eq(order.uid)).fetch();
    }
    @Override
    public List<Order> findAllJpaDsl1() {

        QOrder order = QOrder.order;
        return jpaQueryFactory.selectFrom(order).fetch();
    }

    @Override
    public List<Stu> findByStu() {

        QStu stu = QStu.stu;
        QUser user = QUser.user;
        return jpaQueryFactory.select(stu).from(stu,user).where(stu.id.eq(user.id)).fetch();
    }


    /*
    *
    *  @Override
    public List<Order> findByOrder() {

        QUser user = QUser.user;
        QOrder order = QOrder.order;
        return jpaQueryFactory.select(order).from(user).leftJoin(order).where(user.id.eq(order.uid)).fetch();
        return jpaQueryFactory.select(order)
                .from(user, order)
                .where(user.id.longValue().eq(order.uid.longValue()))
                .fetch();
       //return null;
    * */

    //对表查询



       /* QUser user = QUser.user;
        QOrder order = QOrder.order;
        //定于获取条件
        BooleanBuilder booleanBuilder = new BooleanBuilder();
        //连接条件
        //booleanBuilder.and(user.id.longValue().eq(1L));
        booleanBuilder.and(order.uid.eq(user.id));
        //booleanBuilder.and(user.id.longValue().eq(order.uid.longValue()));
        //使用dsl进行多表联合查询
        QueryResults<Tuple> tupleQueryResults = jpaQueryFactory
                .select(order, user)
                .from(order, user)
                .where(booleanBuilder)
                .fetchResults();
        //遍历转为集合
        List<Order> collect = tupleQueryResults.getResults().stream().map(
                tuple -> {
                    Order order1 = tuple.get(order);
                    return order1;
                }
        ).collect(Collectors.toList());
        //List<Order> collect = tupleQueryResults.getResults().stream().collect(Collectors.toList());
        return collect;*/



}
